﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using Intorise.Common;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Web;
using System.Threading;
using System.Net.Sockets;

namespace Model
{
    public class QdBotEngine : BotEngine
    {
        public QdBotEngine(Player player) : base(player) { }

        public override bool Login()
        {
            string loginUrl = "https://cas.sdo.com/authen/staticLogin.jsonp?callback=a&inputUserId={0}&password={1}&appId=10&areaId=1&serviceUrl=http%3A%2F%2Favd.qidian.com%2FOALoginJump.aspx%3FReturnUrl%3Dhttp%253a%252f%252fgame.qidian.com%252fgame%252fdtszj%252flogin.aspx%26sitetype%3D9999&productVersion=v5&frameType=3&locale=zh_CN&version=21&tag=20&authenSource=2&productId=2&autoLoginFlag=0&_={2}";
            string checkCodeUrl = "https://cas.sdo.com/authen/checkCodeLogin.jsonp?callback=checkCodeLogin_JSONPMethod&guid={0}&password={1}&appId=10&areaId=1&serviceUrl=http%3A%2F%2Favd.qidian.com%2FOALoginJump.aspx%3FReturnUrl%3Dhttp%253a%252f%252fgame.qidian.com%252fgame%252fdtszj%252flogin.aspx%26sitetype%3D9999&productVersion=v5&frameType=3&locale=zh_CN&version=21&tag=20&authenSource=2&productId=2&_={2}";
            string enterGameUrl = "http://gameapp.37.com/controller/enter_game.php?game_id=237&sid={0}&showlogintype=1&refer=37wancom";
            string registerUrl = "http://api.dts.37wan.com/client/?user_name={0}&is_adult=1&sign={1}&server_id=S{2}&client=1&channel=0&real_user=1&user_info=1&tg_pass=0&time={3}";
            string registerServerUrl = null;

            CookieContainer cookies = new CookieContainer();
            ConsoleBLL.WriteLine(player + " 开始登录...");
            var request = net.SendRequest(string.Format(loginUrl, player.PlayerAccount.Username, player.PlayerAccount.Password, DateTime.Now.ToFileTime()), "GET", cookies);
            var response = (HttpWebResponse)request.GetResponse();
            var html = net.GetResponseHtmlGzip(response);

            html = html.Replace("staticLogin_JSONPMethod(", "").Replace(")", "");
            JObject result = (JObject)JsonConvert.DeserializeObject(html);
            if (infoLog)
            {
                ConsoleBLL.WriteLineInfo(player + " login result:" + result);
            }
            var flag = result["return_code"].ToString();
            string code = "";
            string guid = result["data"]["guid"].ToString();
            string codeUrl = result["data"]["checkCodeUrl"].ToString();
            switch (flag)
            {
                case "0":
                    ConsoleBLL.WriteLineError(player + " 用户名密码正确，获取验证码...");
                    CodeForm form = new CodeForm();
                    form.Show(codeUrl);
                    code = form.Code;
                    break;
                default:
                    ConsoleBLL.WriteLineError(player + " 登录失败，账户密码错误");
                    ConsoleBLL.WriteLine(html.ToString());
                    this.player.Status = PlayerStatusEnum.账户密码错误;
                    return false;
            }

            request = net.SendRequest(string.Format(checkCodeUrl, guid, code, DateTime.Now.ToFileTime()), "GET", cookies);
            html = net.GetResponseHtmlGzip(request);
            html = html.Replace("checkCodeLogin_JSONPMethod(", "").Replace(")", "");
            result = (JObject)JsonConvert.DeserializeObject(html);

            string ticket = "";
            switch (result["return_code"].ToString())
            {
                case "0":
                    ConsoleBLL.WriteLineError(player + " 登录成功，验证码正确");
                    ticket = result["data"]["ticket"].ToString();
                    break;
                default:
                    ConsoleBLL.WriteLineError(player + " 登录失败，验证码错误");
                    ConsoleBLL.WriteLine(html.ToString());
                    return false;
            }
            string url = "http://login.sdo.com/sdo/Login/Tool.php?act=setCookie&name=CURRENT_TAB&value=index%7Caa31808801&r=0.17665339703671634";
            request = net.SendRequest(url, "GET", cookies);
            html = net.GetResponseHtml(request);

            url = "http://avd.qidian.com/OALoginJump.aspx?&sitetype=9999&ReturnUrl=http%3A%2F%2Fgame.qidian.com%2Fgame%2FDefault.aspx&ticket=" + ticket;
            request = net.SendRequest(url, "GET", cookies);
            html = net.GetResponseHtml(request);


            url = "http://game.qidian.com/GameAjax.aspx";
            request = net.SendRequest(url, "POST", cookies);
            request.Referer = "http://game.qidian.com/game/Default.aspx";
            request.Headers["X-Requested-With"] = "XMLHttpRequest";
            net.PostData("opName=GetUserGameInfo", request);
            response = (HttpWebResponse)request.GetResponse();
            //url = response.Headers[HttpRequestHeader.ContentLocation];
            html = net.GetResponseHtml(request);

            //获取登录游戏服务器的地址
            result = (JObject)JsonConvert.DeserializeObject(html.Replace("(", "").Replace(")", ""));

            JArray array = (JArray)result["rec"];
            var item = array.Where(x => x["ar"].ToString().Contains(this.player.ServerID.ToString())).FirstOrDefault();
            if (item == null)
            {
                ConsoleBLL.WriteLineError(player + " 登录失败，未找到服务器地址");
                ConsoleBLL.WriteLine(html.ToString());
                return false;
            }
            url = "http://game.qidian.com" + item["url"];
            request = net.SendRequest(url, "GET", cookies);
            html = net.GetResponseHtml(request);

            url = Tools.SubString(html, "id=\"iframe1\" src=\"", "\"", true);
            request = net.SendRequest(url, "GET", cookies);
            html = net.GetResponseHtml(request);

            if (infoLog)
            {
                ConsoleBLL.WriteLineInfo(player + " login enterGameUrl:" + request.RequestUri);
            }

            port = GameHelper.GetPort(html);
            if (port == 0)
            {
                ConsoleBLL.WriteLineError(player + " 无法获取服务器端口，html:");
                ConsoleBLL.WriteLine(html);
                return false;
            }
            head = new byte[] { 0x00, 0x01, 0x87, 0x70 };
            serverNo = Tools.GetAscII(player.PlayerAccount.ServerID);
            accountData = Tools.GetAscII(Tools.SubString(url, "user_name=", "&", true));
            time = Tools.GetAscII(GameHelper.GetTime(html));
            singn = Tools.GetAscII(GameHelper.GetSign(html));
            ip = GameHelper.GetIP(html);

            return true;
        }

        public override bool EnterGameServer()
        {
            DateTime startTime = DateTime.Now;
            Client = new TcpClient(ip, 843);
            var data = Tools.GetAscII("<policy-file-request/>\0");
            net.SendData(Client, data);
            Client.Close();

            Client = new TcpClient(ip, port);
            Begin();

            data = Tools.Contact(head, DataPackager.GetNetworkData((short)serverNo.Length), serverNo, net.GetNetworkBytes((short)accountData.Length), accountData, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A }
                , time, new byte[] { 0x00, 0x01, 0x31, 0x00, 0x20 }, singn
                , new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x31, 0x00, 0x01, 0x30 });
            data = Tools.Contact(net.GetNetworkBytes(data.Length), data);
            net.SendData(Client, data, data.Length);

            while (!player.Entered)
            {
                Thread.Sleep(500);
                if (player.Config.TimeoutLogin < (DateTime.Now - startTime).TotalSeconds) { break; }
            }

            if (!player.Entered)
            {
                ConsoleBLL.WriteLineWaring(player + " 进入游戏超时！");
                Stop();
            }
            return player.Entered;
        }

        private string GetEnterGameData(string html)
        {
            string data = "";

            var __VIEWSTATE = Tools.SubString(html, "id=\"__VIEWSTATE\" value=\"", "\"", true);
            var __EVENTVALIDATION = Tools.SubString(html, "id=\"__EVENTVALIDATION\" value=\"", "\"", true);
            data = "__EVENTTARGET=ctl00%24ContentPlaceHolder1%24lbEnterGame" + this.player.ServerID +
                "&__EVENTARGUMENT=&__VIEWSTATE=" + HttpUtility.UrlEncode(__VIEWSTATE) + "&__EVENTVALIDATION=" + HttpUtility.UrlEncode(__EVENTVALIDATION) +
                "&ctl00%24ContentPlaceHolder2%24HiddenField1=" +
                "&ctl00%24ContentPlaceHolder2%24hddServerName=" + HttpUtility.UrlEncode("起点" + player.ServerID + "区") +
                "&ctl00%24ContentPlaceHolder2%24hddServerHistory=" + HttpUtility.UrlEncode("http://api.qidiandts.6ght.com") +
                "&ctl00%24ContentPlaceHolder2%24hddNameHistory=" + HttpUtility.UrlEncode("起点" + player.ServerID + "区") +
                "&ctl00%24ContentPlaceHolder2%24hddAppId=" +
                "&ctl00%24ContentPlaceHolder2%24hddAppArea=" + player.ServerID;
            return data;
        }
    }
}
